"""
基础协议模块

该模块定义了所有协议类的基类和通用接口。
"""

import logging
import time
from abc import ABC, abstractmethod
from typing import Optional, Tuple, Union, List, Dict, Any


class BaseProtocol(ABC):
    """基础协议类"""

    def __init__(self, log_level: int = logging.INFO):
        """
        初始化基础协议

        Args:
            log_level: 日志级别
        """
        # 配置日志
        logging.basicConfig(level=log_level)
        self.logger = logging.getLogger(self.__class__.__name__)
        self._retry_count = 3
        self._timeout = 0.1
        self._connected = False

    @property
    def is_connected(self) -> bool:
        """获取连接状态"""
        return self._connected

    @property
    def retry_count(self) -> int:
        """获取重试次数"""
        return self._retry_count

    @retry_count.setter
    def retry_count(self, value: int) -> None:
        """设置重试次数"""
        self._retry_count = max(1, min(value, 10))

    @property
    def timeout(self) -> float:
        """获取超时时间"""
        return self._timeout

    @timeout.setter
    def timeout(self, value: float) -> None:
        """设置超时时间"""
        self._timeout = max(0.01, min(value, 1.0))

    def _wait_for_response(self, timeout: Optional[float] = None) -> bool:
        """
        等待响应

        Args:
            timeout: 超时时间(秒)

        Returns:
            bool: 是否等待成功
        """
        if timeout is None:
            timeout = self._timeout
        time.sleep(timeout)
        return True

    @abstractmethod
    def connect(self) -> bool:
        """
        建立连接

        Returns:
            bool: 连接是否成功
        """
        pass

    @abstractmethod
    def disconnect(self) -> None:
        """断开连接"""
        pass

    @abstractmethod
    def write_command(
        self,
        device_id: int,
        cmd: int,
        data: List[int],
        retry_count: Optional[int] = None,
    ) -> bool:
        """
        发送命令

        Args:
            device_id: 设备ID
            cmd: 命令类型
            data: 命令数据
            retry_count: 重试次数

        Returns:
            bool: 命令是否发送成功
        """
        pass

    @abstractmethod
    def read_command(
        self, device_id: int, cmd: int, retry_count: Optional[int] = None
    ) -> bool:
        """
        发送读取命令

        Args:
            device_id: 设备ID
            cmd: 命令类型
            retry_count: 重试次数

        Returns:
            bool: 命令是否发送成功
        """
        pass

    @abstractmethod
    def get_response(
        self, cmd: int, timeout: Optional[float] = None
    ) -> Optional[Union[int, Tuple[int, int], List[int]]]:
        """
        获取响应数据

        Args:
            cmd: 命令类型
            timeout: 超时时间(秒)

        Returns:
            响应数据，如果读取失败则返回None
        """
        pass

    def _validate_data(self, data: List[int]) -> bool:
        """
        验证数据是否有效

        Args:
            data: 数据列表

        Returns:
            bool: 数据是否有效
        """
        return all(0 <= x <= 255 for x in data)

    def _calculate_checksum(self, data: List[int]) -> int:
        """
        计算校验和

        Args:
            data: 数据列表

        Returns:
            int: 校验和
        """
        return sum(data) & 0xFF

    def _format_error(self, error: Exception) -> str:
        """
        格式化错误信息

        Args:
            error: 异常对象

        Returns:
            str: 格式化后的错误信息
        """
        return f"{error.__class__.__name__}: {str(error)}"
